function [hit, nDropped, turn] = game(graph, gSize, pShip, nBombs, timeLag, n, timeLeft, ship, bomber)
%% This files game.m is used to play one game. 
%%

hit = false;    %true if the ship is hit, false if not
nDropped = 0;   %number of bombs dropped by the bomber
lastShipPos = zeros(1,timeLag); %it can store at max where the ship was timeLag turns ago
dropped = [];   %dropped = [droppedTime, droppedPlace], if droppedTime=0 the bomb explodes at the droppedPlace
vn = (n^2+2-n*sqrt(n^2+4))/2; %pShip^2;
[w, bomber_pj] = prepareBomber(vn, n); %maybe calculate n by outgoing arcs....
turn = 0;       %keep track of how many turns the game takes

% for the Strategy Ship : Lee Lee %
if ship==2
global xij
[xij, n_t, w_s]=calcXij();
Sp=[1,1];

 %for ShipStandStill
elseif ship==3
    global nSize
    nSize=n;
    x0=rand(2,1);
    % calculation of the optimal probabilites to go forward and to stand
    % still with the minimax-algorithm
    tmp=fminimax(@probsWithStandingStill, x0);
    pShip=tmp(1);
    sShip=tmp(2);
    
end

if(gSize == inf)
    shipPos = 1;    %starting position
else
    %start somewhere in the middle
    shipPos = (round(gSize(1)/2))*gsize(2) - (round(gSize(2)/2));
end

while((nBombs>0 || ~isempty(dropped)) && ~hit && timeLeft>0)
    turn = turn+1;
    if(~isempty(dropped)) % if a bomb has been dropped
        % decrease the droppedTime by 1
        dropped = dropped - [ones(size(dropped,1),1), zeros(size(dropped,1),1)];
        
        %check if the bomb has exploded and handle it
        for i=1:size(dropped,1)
            if(dropped(i,1) == 0)
                if(shipPos == dropped(i,2))
                    hit = true;
                end
                dropped(i,:) = [];
            end
        end
    end
    
    if(~hit)    %if the ship isn't hit yet, determine the new bombing position and new ship position
        if(nBombs > 0)
            if(bomber==1)   %bomberFerguson is selected
                [dropPos] = bomberFerguson(graph, shipPos, lastShipPos, bomber_pj, timeLag);
            elseif(bomber==2) %bomberGeneric is selected
                dropPos = bomberGeneric( graph, shipPos, lastShipPos, timeLag, turn, -1 );
            elseif(bomber==3) %bomberGeneric with given pShip is selected
                dropPos = bomberGeneric( graph, shipPos, lastShipPos, timeLag, turn, pShip );
            else
                'No such bomber exists!'
            end
            
            if(dropPos > 0)
                dropped = [dropped; timeLag, dropPos];
                nBombs = nBombs-1;
                nDropped = nDropped+1;
            end
        end
        
        if(ship==1) %shipFerguson is selected
            nextShipPos = shipFerguson(graph, shipPos, lastShipPos, pShip);
        elseif(ship==2) %shipLeeLee is selected
           [nextShipPos, Sp] = shipLeeLee(graph, shipPos, lastShipPos, Sp, n_t, w_s);
        elseif(ship==3)
            nextShipPos= shipStandStill(graph, shipPos,lastShipPos,pShip,sShip);
        else
            'No such ship exists!'
        end
        
        %if size = infinite, convert the last positions and the bombed positions to the
        %   moved graph, since we don't move the boat, but the graph
        %else just move the boat to the new position and correct the
        %lastShipPos var
        if(gSize == inf)
            conversion = [nextShipPos, shipPos];
            done = [];
            while(length(done) ~= length(graph))
                temp = ismember(conversion(:,1),done);
                indices = find(temp==0);
                for i=1:length(indices)
                    if(conversion(indices(i),2)>0)
                        orgNeighbours = getNeighbours(conversion(indices(i),1),graph);
                        conNeighbours = zeros(length(orgNeighbours),1);
                        temporary = getNeighbours(conversion(indices(i),2),graph);
                        conNeighbours(1:length(temporary)) = temporary;
                        tOrg = orgNeighbours;   %t stands for temporary variables
                        tCon = conNeighbours;   %org stands for original
                        tOrg1= 0;               %con stands for converted
                        tCon1= 0;               %so we convert the original ones into the converted ones
                        for j=1:length(tOrg)
                            if(ismember(tOrg(j),conversion(:,1)))
                                orgNeighbours(j-tOrg1) = [];
                                tOrg1 = tOrg1+1;
                            end
                            if(tCon(j)~=0 && ismember(tCon(j),conversion(:,2)))
                                conNeighbours(j-tCon1) = [];
                                tCon1 = tCon1+1;
                            end
                        end
                    end
                    
                    for j=1:length(orgNeighbours)
                        if(~ismember(orgNeighbours(j),conversion(:,1)))
                            conversion = [conversion; orgNeighbours(j), conNeighbours(j)];
                        end
                    end
                    done = [done; conversion(indices(i),1)];
                end
            end
            conversion = sortrows(conversion);
            
            newLastPos = [conversion(shipPos,2), zeros(1,length(lastShipPos)-1)];
            for i=2:length(lastShipPos)
                if(lastShipPos(i-1)>0)
                    newLastPos(i) = conversion(lastShipPos(i-1),2);
                end
            end
            lastShipPos = newLastPos;
            
            for i=1:size(dropped,1)
                if(dropped(i,2)>0)
                    dropped(i,2) = conversion(dropped(i,2),2);
                end
            end
        else
            lastShipPos = [shipPos, lastShipPos(1:length(lastShipPos)-1)];
            shipPos = nextShipPos;
        end
    end
    timeLeft = timeLeft-1;
end



%--------------------------------------------------------------------------
function neighbours = getNeighbours(pos, graph)

neighbours = [];
for i=1:length(graph)
    if(graph(pos,i) == 1)
        neighbours = [neighbours;i];
    end
end
